﻿using System;
using BCService.Utils;
using BCCommon;
using BCDto.TMS.LearnTrain.DriverLearningTrainRecord.DriverLearningTrainRecordRequest;
using BCDto.TMS.LearnTrain.DriverLearningTrainRecord;
using BCEntity.TMS.LearningTrain.DriverLearningTrainRecord;
using BCData.TMS.Driver;
using BCData.TMS.LearningTrain;
using BCEntity.Common.EntityNameConst;
using BCDto.Sim.Admin.Admin;
using BCCommon.TMS.Driver;
using System.Collections.Generic;
using BCData.TMS.LearningTrain.DriverLearningTrainRecord;
using BCDto.TMS.LearnTrain.PendingLearningVehicle.PendingLearningVehicleRequestDto;

namespace BCService.TMS.LearningTrain.DriverLearningTrainRecord
{
    public class DriverLearningTrainRecordService : IDriverLearningTrainRecordService
    {
        #region var
        private readonly IDatabaseContext databaseContext;
        private readonly IDriverLearningTrainRecordData driverLearningTrainRecordData;
        private readonly IDriverData driverData;
        private readonly IPendingLearningVehicleData pendingLearningVehicleData;
        private readonly IVehicleTrainingScheduleRecordData vehicleTrainingScheduleRecordData;
        private readonly IRedisService redisService;
        private readonly string key = string.Format("{0}", EntityNameConst.DriverLearningTrainRecordEntity);
        private readonly string keyView = string.Format("{0}", EntityNameConst.DriverLearningTrainRecordViewEntity);
        private readonly string keyDriverEntity = string.Format("{0}", EntityNameConst.DriverEntity);
        #endregion

        #region 构造函数
        public DriverLearningTrainRecordService(IDriverLearningTrainRecordData driverLearningTrainRecordData,
            IDatabaseContext databaseContext,
            IDriverData driverData,
            IPendingLearningVehicleData pendingLearningVehicleData,
            IVehicleTrainingScheduleRecordData vehicleTrainingScheduleRecordData,
            IRedisService redisService)
        {
            this.driverLearningTrainRecordData = driverLearningTrainRecordData;
            this.databaseContext = databaseContext;
            this.driverData = driverData;
            this.pendingLearningVehicleData = pendingLearningVehicleData;
            this.vehicleTrainingScheduleRecordData = vehicleTrainingScheduleRecordData;
            this.redisService = redisService;
        }
        #endregion



        #region Add
        /// <summary>
        /// 添加新DriverLearningTrainRecord纪录
        /// </summary>
        /// <param name="requestDto">安全培训通过</param>
        /// <param name="driverId">司机id</param>
        /// <returns></returns>
        public DriverLearningTrainRecordDto Add(DriverLearningTrainRecordRequestDto requestDto, long driverId)
        {
            var driver = this.driverData.GetDriverByIdAsync(driverId).Result;
            if (driver == null)
            {
                throw new ArgumentException(" 获取当前司机信息失败 ");
            }
            if (driver.IsLearnTrainPassed)
            {
                throw new ArgumentException(" 您已通用安全培训,不可重复通过 ");
            }
            var pendingLearningVehicle = this.pendingLearningVehicleData.GetEntityByDriverId(driverId).Result;
            if (pendingLearningVehicle == null)
            {
                throw new ArgumentException(" 您当前不是待培训司机,不可通过 ");
            }
            if (!pendingLearningVehicle.VehicleTrainingScheduleRecordId.HasValue)
            {
                throw new ArgumentException(" 您当前未被安排培训,不可通过 ");
            }
            if (pendingLearningVehicle.IsAbsenteeism)
            {
                throw new ArgumentException(" 您被管理员设定为缺席,不可通过,如有必要,请联系管理员 ");
            }
            var vehicleTrainingScheduleRecord = this.vehicleTrainingScheduleRecordData.GetEntityAsync(pendingLearningVehicle.VehicleTrainingScheduleRecordId.Value).Result;
            if (vehicleTrainingScheduleRecord == null)
            {
                throw new ArgumentException(" 当前培训考试不存在,不可通过 ");
            }
            if (!(vehicleTrainingScheduleRecord.TrainingStartDate <= DateTime.Now.Date))
            {
                throw new ArgumentException(" 当前培训考试尚未开始,不可通过 ");
            }
            if (!(vehicleTrainingScheduleRecord.TrainingEndDate >= DateTime.Now.Date))
            {
                throw new ArgumentException(" 当前培训考试已结束,不可通过 ");
            }
            var entity = new DriverLearningTrainRecordEntity
            {
                DriverId = driverId,
                PendingLearningVehicleId = pendingLearningVehicle.PendingLearningVehicleId,
                VehicleTrainingScheduleRecordId = vehicleTrainingScheduleRecord.VehicleTrainingScheduleRecordId,
                Postion_X = requestDto.Postion_X,
                Postion_Y = requestDto.Postion_Y,
                PhotoAddress = requestDto.PhotoAddress,
                PostionAddress = requestDto.PostionAddress,
                CreateTime = DateTime.Now,
            };
            this.databaseContext.BeginTransaction();
            this.driverData.LearnTrainSignAsync(driverId,true).GetAwaiter().GetResult();
            var result = this.driverLearningTrainRecordData.InsertAsync(entity).GetAwaiter().GetResult();
            this.databaseContext.Commit();
            this.redisService.DeleteMultipleKey(key, false);
            this.redisService.DeleteMultipleKey(keyDriverEntity, false);
            return result.As<DriverLearningTrainRecordDto>();
        }
        #endregion


        public bool LearnTrainPassed(AdminDto admin,long vehicleTrainingScheduleRecordId, PendingLearningVehicleIdRequestDto requestDto)
        {
            var vehicleTrainingScheduleRecord = this.vehicleTrainingScheduleRecordData
                .GetEntityAsync(vehicleTrainingScheduleRecordId).Result;
            if (vehicleTrainingScheduleRecord == null)
            {
                throw new ArgumentException(" 当前培训考试不存在,不可通过 ");
            }

            if (vehicleTrainingScheduleRecord.AgentRecordId!=admin.AgentRecord.AgentRecordId)
            {
                throw new ArgumentException(" 不可操作别人的考试 ");
            }

            if (!(vehicleTrainingScheduleRecord.TrainingStartDate <= DateTime.Now.Date))
            {
                throw new ArgumentException(" 当前培训考试尚未开始,不可通过 ");
            }

            if (!(vehicleTrainingScheduleRecord.TrainingEndDate >= DateTime.Now.Date))
            {
                throw new ArgumentException(" 当前培训考试已结束,不可通过 ");
            }

            if (requestDto.PendingLearningVehicleId.HasValue)
            {
                var pendingLearningVehicle =
                    this.pendingLearningVehicleData.GetEntityAsync(requestDto.PendingLearningVehicleId.Value).Result;
                if (pendingLearningVehicle == null)
                {
                    throw new ArgumentException("当前待培训骑手不存在");
                }

                if (pendingLearningVehicle.IsAbsenteeism)
                {
                    throw new ArgumentException("当前待培训骑手已缺席");
                }

                var driver = this.driverData.GetDriverByIdAsync(pendingLearningVehicle.DriverId).Result;
                if (!driver.IsLearnTrainSign)
                {
                    throw new ArgumentException("当前骑手未签到");
                }

                if (driver.IsLearnTrainPassed)
                {
                    throw new ArgumentException("当前骑手已考试通过");
                }

                this.driverData.LearnTrainPassedAsync(driver.DriverId).GetAwaiter().GetResult();
            }
            else
            {
                var list = pendingLearningVehicleData.GetList(vehicleTrainingScheduleRecordId).Result;
                foreach (var item in list)
                {
                    var driver = this.driverData.GetDriverByIdAsync(item.DriverId).Result;
                    if (!item.IsAbsenteeism && driver.IsLearnTrainSign && !driver.IsLearnTrainPassed)
                    {
                        this.driverData.LearnTrainPassedAsync(item.DriverId).GetAwaiter().GetResult();
                    }
                }
            }

            return true;
        }

        public PageableList<DriverLearningTrainRecordViewDto> GetListAsync(AdminDto admin, string driverName,
             DriverRoleType? driverRoleType, string vehicleNo, string phone, long? trainingSiteConfigId, DateTime? trainingStartDate,
             DateTime? trainingEndDate, DateTime? learnTrainPassedStartDate, DateTime? learnTrainPassedEndDate,
             DateTime? learnTrainSignStartDate, DateTime? learnTrainSignEndDate,
             int pageIndex, int pageSize)
        {
            if (admin.AgentRecord == null)
            {
                throw new ArgumentException("  用户认证失败,错误操作 ");
            }
            string cacheKey = this.redisService.GetKey(keyView, admin.AgentRecord.AgentRecordId, driverName, driverRoleType, vehicleNo,
                    phone, trainingSiteConfigId, trainingStartDate, trainingEndDate, learnTrainPassedStartDate, learnTrainPassedEndDate,
                    learnTrainSignStartDate, learnTrainSignEndDate, pageIndex, pageSize);
            var resultRedis = this.redisService.TryGet(cacheKey, () =>
            {
                var (list, count) = this.driverLearningTrainRecordData.GetListAsync(admin.AgentRecord.AgentRecordId, driverName, driverRoleType, vehicleNo,
                    phone, trainingSiteConfigId, trainingStartDate, trainingEndDate, learnTrainPassedStartDate, learnTrainPassedEndDate,
                    learnTrainSignStartDate, learnTrainSignEndDate,
                    pageIndex, pageSize).GetAwaiter().GetResult();
                return new PageableList<DriverLearningTrainRecordViewDto>
                {
                    Items = list.As<IEnumerable<DriverLearningTrainRecordViewDto>>(),
                    Count = count,
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    ServerTime = DateTime.Now,
                };
            }, TimeSpan.FromDays(1));
            return resultRedis;
        }
 
    }
}